package inge_soft.gestoriusNuevo.business.controller.implementation;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import inge_soft.gestoriusNuevo.business.controller.validation.FiltrosEventos;
import inge_soft.gestoriusNuevo.business.service.abstraction.IInstitucionService;
import inge_soft.gestoriusNuevo.business.service.abstraction.IServicioEvento;

import inge_soft.gestoriusNuevo.persistence.entity.implementation.Evento;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Institucion;
import inge_soft.gestoriusNuevo.support.SecurityUtil;

import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;

import org.zkoss.zhtml.Messagebox;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class EventosViewModel {

	private static final String message = "Total eventos filtrados = %d ";
	private Evento evento;
	private List<Evento> listaEventos = new ArrayList<Evento>();
	private List<Evento> listaEventosAux = new ArrayList<Evento>();
	private FiltrosEventos filtro;
	@WireVariable("institucionService")
	private IInstitucionService intituciones;
	@WireVariable("eventoService")
	private IServicioEvento ievento;
	private boolean parametro;

	@Init
	public void init() {
		Institucion institucionArg = (Institucion) Sessions.getCurrent()
				.getAttribute("institucionArg");
		
		if (institucionArg == null) {
			filtro = new FiltrosEventos();
		} else {
			filtro = new FiltrosEventos(institucionArg);
			parametro = true;
			Sessions.getCurrent().setAttribute("institucionArg",null);
		}
		listaEventos.addAll(cargarEventos());
		listaEventosAux.addAll(cargarEventos());
		System.out.println(listaEventos.size() + "eventos");
	}

	public List<Evento> cargarEventos() {
		List<Evento> lista = new ArrayList<Evento>();
		List<Institucion> listaInst = new ArrayList<Institucion>();
		listaInst.addAll(intituciones.obtenerInstituciones(SecurityUtil
				.getUserName()));

		int contador = 0;
		while (!listaInst.isEmpty() && contador < listaInst.size()) {
			if (!listaInst.get(contador).getListaEventos().isEmpty()) {
				lista.addAll(listaInst.get(contador).getListaEventos());

			}
			contador++;
		}
		return lista;
	}

	@AfterCompose
	public void doAfterCompose() {
		if (parametro) {//Si entro con parametro de institucion, filtrar al iniciar!
			try {
				this.filtrarEventos();
			} catch (Exception e1) {
				// No deberia generar problemas, pero lo pide 
				Messagebox.show("Error en el parseo de los filtros");
			}
		}
	}

	public IInstitucionService getIntituciones() {
		return intituciones;
	}

	public void setIntituciones(IInstitucionService intituciones) {
		this.intituciones = intituciones;
	}

	public Evento getEvento() {
		return evento;
	}

	public void setEvento(Evento evento) {
		this.evento = evento;
	}

	public List<Evento> getListaEventos() {
		return listaEventos;
	}

	public FiltrosEventos getFiltro() {
		return filtro;
	}

	public void setFiltro(FiltrosEventos filtro) {
		this.filtro = filtro;
	}

	public static String getMessage() {
		return message;
	}

	public void setListaEventos(List<Evento> listaEventos) {
		this.listaEventos = listaEventos;
	}

	public String getmensaje() {
		return String.format(message, listaEventos.size());
	}

	@Command
	public void nuevo() {
		Sessions.getCurrent().setAttribute("evento", null);
		Executions.getCurrent()
				.sendRedirect("index.zul?destino=Evento.zul", "");
	}

	@Command
	public void editar(@BindingParam("ite") Evento evento) {

		Sessions.getCurrent().setAttribute("evento", evento);
		Executions.getCurrent()
				.sendRedirect("index.zul?destino=Evento.zul", "");

	}

	@Command
	public void actividades(@BindingParam("ite") Evento evento) {
		Sessions.getCurrent().setAttribute("evento", evento.getId());
		Executions.getCurrent().sendRedirect(
				"index.zul?destino=ListaActividades.zul", "");
	}

	@Command
	@NotifyChange({ "listaEventos", "filtro" })
	public void filtrarEventos() throws ParseException {
		listaEventos.clear();
		listaEventos.addAll(filtar(this.filtro));

	}

	public List<Evento> filtar(FiltrosEventos filtro) throws ParseException {
		List<Evento> lista = new ArrayList<Evento>();

		String nombreInstitucion = filtro.getNombreInstitucion().toLowerCase();
		String nombreCategoria = filtro.getNombreCategoria().toLowerCase();
		String nombreEstado = filtro.getNombreEstado().toLowerCase();
		Date fechaInicio = filtro.getFechaInicio();
		Date fechaFin = filtro.getFechaFin();

		if (fechaInicio == null) {
			fechaInicio = ievento.primerFechaEventos();
		}
		if (fechaFin == null) {
			fechaFin = new Date(Long.MAX_VALUE);// Agregado el max value, para que si no tiene una fecha de fin cargada, que compare con la fecha mas grande posible en java
		}
		if (filtro.getNombreInstitucion().compareToIgnoreCase("") == 0
				&& filtro.getNombreEstado().compareToIgnoreCase("") == 0
				&& filtro.getNombreCategoria().compareToIgnoreCase("") == 0
				&& filtro.getFechaInicio() == null
				&& filtro.getFechaFin() == null) {

			return listaEventosAux;
		}

		for (Iterator<Evento> even = listaEventosAux.iterator(); even.hasNext();) {
			Evento aux = even.next();
			System.out.println("evento: "+ aux.getNombre().toLowerCase());
			System.out.println("nombre del evento actual: "+ aux.getInstitucion().getNombreFantasia());
			System.out.println("contiene el nombre de institucion: "+aux.getInstitucion().getNombreFantasia().toLowerCase().contains(nombreInstitucion));
			System.out.println("nombre de institucion por el que filtra: "+ nombreInstitucion);
			System.out.println("categoria: "+ aux.getCategoria().getNombre().toLowerCase());
			System.out.println("contiene la categoria: "+ aux.getCategoria().getNombre().toLowerCase().contains(nombreCategoria));
			System.out.println("fecha inicio: "+ aux.getFechaInicio());
			System.out.println("resultado de la fecha inicio: " + aux.getFechaInicio().compareTo(fechaInicio));
			System.out.println("fecha fin: "+ aux.getFechaFin());
			System.out.println("comparacion fecha fin:" + fechaFin);
			System.out.println("resultado fecha fin: " + aux.getFechaFin().compareTo(fechaFin));
			
			if (aux.getInstitucion().getNombreFantasia().toLowerCase()
					.contains(nombreInstitucion)
					&& aux.getCategoria().getNombre().toLowerCase()
							.contains(nombreCategoria)
					&& aux.getEstado().getNombre().toLowerCase()
							.contains(nombreEstado)
					&& aux.getFechaInicio().compareTo(fechaInicio) >= 0
					&& aux.getFechaFin().compareTo(fechaFin) <= 0) {
				lista.add(aux);

			}

		}
		return lista;
	}

	@Command
	public void Cancelar(@BindingParam("ite") Evento evento) {
		System.out
				.println("lista actividades: " + evento.getListaActividades());
		if (evento.getListaActividades() == null)
			System.out.println("lista actividades en null");
		ievento.cancelarEvento(evento);
		Executions.getCurrent().sendRedirect("index.zul?destino=Eventos.zul",
				"");
	}

}
